/***************************************************************************
 *   Copyright (C) 2007, 2008 by Andreas Theofilu                          *
 *   andreas@theosys.at                                                    *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation version 3 of the License.                *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/

#include "garmin.h"
#include <stdio.h>
#include <string.h>

struct GARMIN_ERROR
{
	int idx;
	err_type type;
	char *gerr;
	struct GARMIN_ERROR *next;
} GARMIN_ERROR;

static struct GARMIN_ERROR *gerr = NULL;

void garmin_queue_error(char *str, err_type type)
{
int idx = 0;
char *p, *s;

	if (!str)
	   return;

	switch (type)
	{
	   case err_info:
	      p = strdup("Information");
	   break;

	   case err_warning:
	      p = strdup("Warning");
	   break;

	   case err_error:
	      p = strdup("Error");
	   break;

	   case err_fatal:
	      p = strdup("Fatal error");
	   break;

	   default:
	      p = strdup("Unknown");
	}

	if ((s = (char *)malloc(strlen(p) + strlen(str) + 10)) == NULL)
	{
	   if (p)
	      free(p);

	   fprintf(stderr, "Not enough memory!\n");
	   return;
	}

	sprintf(s, "%s:\n%s", p, str);
	free(p);

	if (!gerr)
	{
	   if ((gerr = (struct GARMIN_ERROR *)malloc(sizeof(struct GARMIN_ERROR))) == NULL)
	   {
	      fprintf(stderr, "Not enough memory!\n");
	      return;
	   }

	   gerr->idx = idx;
	   gerr->type = type;
	   gerr->gerr = s;
	   gerr->next = NULL;
	}
	else
	{
	   struct GARMIN_ERROR *akt, *n;

	   if ((n = (struct GARMIN_ERROR *)malloc(sizeof(struct GARMIN_ERROR))) == NULL)
	   {
	      fprintf(stderr, "Not enough memory!\n");
	      return;
	   }

	   /* Find last error message */
	   akt = gerr;

	   while (akt->next)
	   {
	      akt = akt->next;
	      idx++;
	   }

	   idx++;
	   n->idx = idx;
	   n->type = type;
	   n->gerr = s;
	   n->next = NULL;
	   akt->next = n;
	}
}

void garmin_clear_errors()
{
struct GARMIN_ERROR *akt, *old;

	akt = gerr;

	while (akt)
	{
	   old = akt;
	   akt = akt->next;

	   if (old->gerr)
	      free(old->gerr);

	   free(old);
	}

	gerr = NULL;
}

char *garmin_get_first_error(int *key)
{
	if (key)
	   *key = gerr->idx;

	return gerr->gerr;
}

char *garmin_get_next_error(int *key)
{
struct GARMIN_ERROR *akt;

	if (!key)
	   return NULL;

	if (*key == -1)
	   return garmin_get_first_error(key);

	akt = gerr;

	while (akt)
	{
	   if (*key == akt->idx && akt->next)
	   {
	      *key = akt->next->idx;
	      return akt->next->gerr;
	   }

	   akt = akt->next;
	}

	return NULL;
}

int garmin_count_error()
{
struct GARMIN_ERROR *akt = gerr;
int idx = 0;

	while (akt)
	{
	   idx++;
	   akt = akt->next;
	}

	return idx;
}
